package ${classPath};

import java.util.ArrayList;
import java.util.Set;
import java.util.List;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import top.lemna.base.utils.BeanUtils;

@Slf4j
@RestController
@RequestMapping("/${artifact}/${domain}")
@Api(tags = {"${classComment}服务"})
public class ${domain}Controller {

 <#assign Vo="${domain}Vo" instance="${domain?substring(0,1)?lower_case}${domain?substring(1)}"/>
 
  @Autowired
  private ${domain}Service service;

  @ApiOperation(value = "获取指定的${classComment}信息", notes = "根据 id 获取指定的${classComment}信息")
  @ApiImplicitParams({//
      @ApiImplicitParam(//
          name = "id", value = "${classComment}id", required = true, paramType = "path"//
      )//
  })
  @GetMapping("{id}")
  public ${Vo} get(@PathVariable("id") Long id) {
    log.info("${domain} 查询 id:{}", id);
    ${domain} ${instance} = service.findById(id);
    return new ${Vo}(${instance});
  }

  @ApiOperation(value = "查询${classComment}信息", notes = "根据参数查询${classComment}信息，返回${classComment}分页列表")
  @GetMapping
  public Page<${Vo}> search(//
      @Valid ${domain}QueryCommand command, //
      @PageableDefault(sort = "id", direction = Sort.Direction.DESC) Pageable pageable //
  ) {
    log.info("${domain} 查询 command:{}, pageable:{}", command, pageable);
    ${domain}Query query = command.convertToQuery();
    Page<${domain}> page = service.findAll(query.getSpecification(), pageable);
    return convert(page, pageable);
  }
    
  @ApiOperation(value = "新增${classComment}信息", notes = "新增${classComment}信息，成功后返回新增的${classComment}对象", produces = "application/json")
  @PostMapping
  public ${Vo} add(@RequestBody @Valid ${domain}AddCommand command) {
    log.info("${domain} 新增 command:{}", command);
    ${domain} entity = service.create(command.convertToBo());
    return new ${Vo}(entity);
  }
  
  @ApiOperation(value = "修改${classComment}信息", notes = "修改${classComment}信息，成功后返回修改后的${classComment}对象", produces = "application/json")
  @PutMapping("{id}")
  public ${Vo} edit(@PathVariable("id") Long id, @RequestBody @Valid ${domain}EditCommand command) {
    log.info("${domain} 修改 id:{}, command:{}", id, command);
    ${domain} entity = service.edit(id, command.convertToBo());
    return new ${Vo}(entity);
  }
  
  @ApiOperation(value = "删除${classComment}信息", notes = "根据 id 删除指定的${classComment}")
  @DeleteMapping("{id}")
  public void del(@PathVariable("id") Long id) {
    log.info("${domain} 删除 id:{}", id);
    service.delete(id);
  }
  
  @ApiOperation(value = "批量删除${classComment}信息", notes = "根据 id 批量删除${classComment}")
  @DeleteMapping
  public void del(Set<Long> ids) {
    log.info("${domain} 批量删除 ids:{}", ids);
    for (Long id : ids) {
      service.delete(id);
    }
  }
  
  private Page<${Vo}> convert(Page<${domain}> page, Pageable pageable) {
    List<${Vo}> newList = new ArrayList<>();
    List<${domain}> list = page.getContent();
    for (${domain} ${instance} : list) {
      newList.add(new ${Vo}(${instance}));
    }

    Page<${Vo}> newPage = new PageImpl<${Vo}>(newList, pageable, page.getTotalElements());
    return newPage;
  }
}
